<template>
  <el-row :gutter="18">
    <el-col :sm="24" :md="18" :lg="18">
      <el-card shadow>
        <div slot="header">
          <el-row :gutter="18">
            <el-col :sm="5" :md="5" :lg="7">
              <span class="panel-title hidden-xs-only">{{
                $t('m.Problem_List')
              }}</span>
            </el-col>
            <el-col :xs="8" :sm="3" :md="3" :lg="3" style="padding-top: 6px;">
              <el-dropdown
                class="drop-menu"
                @command="filterByOJ"
                placement="bottom"
                trigger="hover"
              >
                <span class="el-dropdown-link">
                  {{
                    query.oj === 'Mine' || query.oj === ''
                      ? $t('m.My_OJ')
                      : query.oj === 'All'
                      ? $t('m.All')
                      : query.oj
                  }}
                  <i class="el-icon-caret-bottom"></i>
                </span>
                <el-dropdown-menu slot="dropdown">
                  <el-dropdown-item command="All">{{
                    $t('m.All')
                  }}</el-dropdown-item>
                  <el-dropdown-item command="Mine">{{
                    $t('m.My_OJ')
                  }}</el-dropdown-item>
                  <el-dropdown-item
                    :command="remoteOj.key"
                    v-for="(remoteOj, index) in REMOTE_OJ"
                    :key="index"
                    >{{ remoteOj.name }}</el-dropdown-item
                  >
                </el-dropdown-menu>
              </el-dropdown>
            </el-col>
            <el-col :xs="8" :sm="3" :md="3" :lg="3" style="padding-top: 6px;">
              <el-dropdown
                class="drop-menu"
                @command="filterByDifficulty"
                placement="bottom"
                trigger="hover"
              >
                <span class="el-dropdown-link">
                  {{
                    query.difficulty === 'All' || query.difficulty === ''
                      ? $t('m.Level')
                      : getLevelName(query.difficulty)
                  }}
                  <i class="el-icon-caret-bottom"></i>
                </span>
                <el-dropdown-menu slot="dropdown">
                  <el-dropdown-item command="All">{{
                    $t('m.All')
                  }}</el-dropdown-item>
                  <el-dropdown-item
                    :command="key"
                    v-for="(value, key, index) in PROBLEM_LEVEL"
                    :key="index"
                    >{{ getLevelName(key) }}</el-dropdown-item
                  >
                </el-dropdown-menu>
              </el-dropdown>
            </el-col>
            <el-col :xs="8" :sm="3" :md="2" :lg="3" style="padding-top: 6px;">
              <vxe-checkbox
                v-model="tagVisible"
                @change="changeTagVisible(tagVisible)"
                >{{ $t('m.Tags') }}</vxe-checkbox
              >
            </el-col>
            <el-col :xs="18" :sm="7" :md="7" :lg="5" class="top-pt">
              <vxe-input
                v-model="query.keyword"
                :placeholder="$t('m.Enter_keyword')"
                type="search"
                size="medium"
                @search-click="filterByKeyword"
                @keyup.enter.native="filterByKeyword"
              ></vxe-input>
            </el-col>
            <el-col :sm="3" :md="3" :lg="3" class="hidden-xs-only">
              <el-button
                type="primary"
                size="small"
                icon="el-icon-refresh"
                round
                @click="onReset"
                >{{ $t('m.Reset') }}</el-button
              >
            </el-col>
            <el-col :xs="6" class="hidden-sm-and-up top-pt">
              <el-button
                type="primary"
                size="small"
                icon="el-icon-refresh"
                circle
                @click="onReset"
              ></el-button>
            </el-col>
          </el-row>
          <template v-if="filterTagList.length > 0 && buildFilterTagList">
            <el-row>
              <strong class="search-tag">搜索标签</strong>
              <el-tag
                :key="index"
                v-for="(tag, index) in filterTagList"
                closable
                :color="tag.color ? tag.color : '#409eff'"
                effect="dark"
                :disable-transitions="false"
                @close="removeTag(tag)"
                size="medium"
                class="tag"
              >
                {{ tag.name }}
              </el-tag>
            </el-row>
          </template>
        </div>
        <vxe-table
          border="inner"
          stripe
          ref="problemList"
          auto-resize
          :loading="loadings.table"
          @cell-mouseenter="cellHover"
          :data="problemList"
        >
          <vxe-table-column title="" width="30" v-if="isAuthenticated">
            <template v-slot="{ row }">
              <template v-if="isGetStatusOk">
                <el-tooltip
                  :content="JUDGE_STATUS[row.myStatus]['name']"
                  placement="top"
                >
                  <template v-if="row.myStatus == 0">
                    <i
                      class="el-icon-check"
                      :style="getIconColor(row.myStatus)"
                    ></i>
                  </template>

                  <template v-else-if="row.myStatus != -10">
                    <i
                      class="el-icon-minus"
                      :style="getIconColor(row.myStatus)"
                    ></i>
                  </template>
                </el-tooltip>
              </template>
            </template>
          </vxe-table-column>
          <vxe-table-column
            field="problemId"
            :title="$t('m.Problem_ID')"
            width="150"
            show-overflow
          ></vxe-table-column>

          <vxe-table-column
            field="title"
            :title="$t('m.Problem')"
            min-width="150"
            show-overflow
          >
            <template v-slot="{ row }">
              <a @click="getProblemUri(row.problemId)" class="title-a">{{
                row.title
              }}</a>
            </template>
          </vxe-table-column>

          <vxe-table-column
            field="difficulty"
            :title="$t('m.Level')"
            min-width="100"
          >
            <template v-slot="{ row }">
              <span
                class="el-tag el-tag--small"
                :style="getLevelColor(row.difficulty)"
                >{{ getLevelName(row.difficulty) }}</span
              >
            </template>
          </vxe-table-column>

          <vxe-table-column
            field="tag"
            :title="$t('m.Tags')"
            min-width="230"
            visible="false"
          >
            <template v-slot="{ row }">
              <span
                class="el-tag el-tag--small"
                :style="
                  'cursor: pointer;margin-right:7px;color:#FFF;background-color:' +
                    (tag.color ? tag.color : '#409eff')
                "
                v-for="tag in row.tags"
                :key="tag.id"
                @click="addTag(tag)"
                >{{ tag.name }}</span
              >
            </template>
          </vxe-table-column>
          <vxe-table-column
            field="total"
            :title="$t('m.Total')"
            min-width="80"
          ></vxe-table-column>
          <vxe-table-column
            field="ac"
            :title="$t('m.AC_Rate')"
            min-width="120"
            align="center"
          >
            <template v-slot="{ row }">
              <span>
                <el-tooltip
                  effect="dark"
                  :content="row.ac + '/' + row.total"
                  placement="top"
                  style="margin-top:0"
                >
                  <el-progress
                    :text-inside="true"
                    :stroke-width="20"
                    :color="customColors"
                    :percentage="getPassingRate(row.ac, row.total)"
                  ></el-progress>
                </el-tooltip>
              </span>
            </template>
          </vxe-table-column>
        </vxe-table>
      </el-card>
      <Pagination
        :total="total"
        :page-size="limit"
        @on-change="pushRouter"
        :current.sync="query.currentPage"
        @on-page-size-change="onPageSizeChange"
        :layout="'prev, pager, next, sizes'"
      ></Pagination>
    </el-col>

    <el-col :sm="24" :md="6" :lg="6">
      <el-card style="text-align:center">
        <span class="panel-title">{{ currentProblemTitle }}</span>
        <el-row v-for="(record, index) in problemRecord" :key="index">
          <el-col :xs="5" :sm="4" :md="6" :lg="4" style="margin-top: 10px;">
            <el-tag
              effect="dark"
              size="small"
              :color="JUDGE_STATUS[record.status].rgb"
              >{{ JUDGE_STATUS[record.status].short }}</el-tag
            >
          </el-col>
          <el-col :xs="19" :sm="20" :md="18" :lg="20">
            <el-progress
              :text-inside="true"
              :stroke-width="20"
              :percentage="record.count"
              :color="JUDGE_STATUS[record.status].rgb"
            ></el-progress>
          </el-col>
        </el-row>
      </el-card>
      <el-card :padding="10" style="margin-top:20px">
        <div slot="header" style="text-align: center;">
          <span class="taglist-title">{{ OJName + ' ' + $t('m.Tags') }}</span>
        </div>
        <template v-if="tagList.length > 0" v-loading="loadings.tag">
          <el-button
            v-for="tag in tagList"
            :key="tag.id"
            @click="addTag(tag)"
            type="ghost"
            size="mini"
            class="tag-btn"
            :style="
              'color:#FFF;background-color:' +
                (tag.color ? tag.color : '#409eff')
            "
            >{{ tag.name }}
          </el-button>
          <el-button long id="pick-one" @click="pickone">
            <i class="fa fa-random"></i>
            {{ $t('m.Pick_a_random_question') }}
          </el-button>
        </template>
        <template v-else
          ><el-empty :description="$t('m.No_Data')"></el-empty>
        </template>
      </el-card>
    </el-col>
  </el-row>
</template>

<script>
import { mapGetters } from 'vuex';
import api from '@/common/api';
import {
  PROBLEM_LEVEL,
  JUDGE_STATUS,
  JUDGE_STATUS_RESERVE,
  REMOTE_OJ,
} from '@/common/constants';
import utils from '@/common/utils';
import myMessage from '@/common/message';
import 'element-ui/lib/theme-chalk/display.css';
import Pagination from '@/components/oj/common/Pagination';
export default {
  name: 'ProblemList',
  components: {
    Pagination,
  },
  data() {
    return {
      PROBLEM_LEVEL: {},
      JUDGE_STATUS: {},
      JUDGE_STATUS_RESERVE: {},
      REMOTE_OJ: {},
      tagList: [],
      tagVisible: false,
      currentProblemTitle: '',
      problemRecord: [],
      problemList: [],
      limit: 30,
      total: 100,
      isGetStatusOk: false,
      loadings: {
        table: true,
        tag: true,
      },
      filterConfig: { remote: true },
      filterTagList: [],
      buildFilterTagList: false,
      routeName: '',
      query: {
        keyword: '',
        difficulty: 'All',
        oj: '',
        tagId: '',
        currentPage: 1,
      },
      customColors: [
        { color: '#909399', percentage: 20 },
        { color: '#f56c6c', percentage: 40 },
        { color: '#e6a23c', percentage: 60 },
        { color: '#1989fa', percentage: 80 },
        { color: '#67c23a', percentage: 100 },
      ],
    };
  },
  created() {
    this.init();
  },

  mounted() {
    this.PROBLEM_LEVEL = Object.assign({}, PROBLEM_LEVEL);
    this.JUDGE_STATUS_RESERVE = Object.assign({}, JUDGE_STATUS_RESERVE);
    this.JUDGE_STATUS = Object.assign({}, JUDGE_STATUS);
    this.REMOTE_OJ = Object.assign({}, REMOTE_OJ);
    this.currentProblemTitle = this.$i18n.t('m.Touch_Get_Status');
    // 初始化
    this.problemRecord = [
      { status: 0, count: 100 },
      { status: -1, count: 100 },
      { status: 1, count: 100 },
      { status: 2, count: 100 },
      { status: 3, count: 100 },
      { status: -3, count: 100 },
      { status: -2, count: 100 },
      { status: 4, count: 100 },
    ];
    this.getTagList(this.query.oj);
    this.loadings.table = true;
    setTimeout(() => {
      // 将指定列设置为隐藏状态
      this.$refs.problemList.getColumnByField('tag').visible = false;
      this.$refs.problemList.refreshColumn();
      this.loadings.table = false;
    }, 200);
    this.getData();
  },
  methods: {
    init() {
      this.routeName = this.$route.name;
      let query = this.$route.query;
      this.query.difficulty = query.difficulty || '';
      this.query.oj = query.oj || 'Mine';
      this.query.keyword = query.keyword || '';
      try {
        this.query.tagId = JSON.parse(query.tagId);
      } catch (error) {
        this.query.tagId = [];
      }
      this.query.currentPage = parseInt(query.currentPage) || 1;
      if (this.query.currentPage < 1) {
        this.query.currentPage = 1;
      }
    },

    getData() {
      this.getProblemList();
    },

    pushRouter() {
      this.$router.push({
        path: '/problem',
        query: this.query,
      });
    },
    onPageSizeChange(pageSize) {
      this.limit = pageSize;
      this.getProblemList();
    },
    getPercentage(partNumber, total) {
      return partNumber == 0
        ? 0
        : Math.round((partNumber / total) * 10000) / 100.0;
    },
    getPassingRate(ac, total) {
      if (!total) {
        return 0;
      }
      return ((ac / total) * 100).toFixed(2);
    },
    // 处理触碰或鼠标悬浮某题目，在右上方显示对应的提交数据
    cellHover(event) {
      let problem = event.data[event.rowIndex];
      let record;
      if (problem.type == 0) {
        // ACM类型题目
        record = [
          { status: 0, count: this.getPercentage(problem.ac, problem.total) },
          { status: -1, count: this.getPercentage(problem.wa, problem.total) },
          { status: 1, count: this.getPercentage(problem.tle, problem.total) },
          { status: 2, count: this.getPercentage(problem.mle, problem.total) },
          { status: 3, count: this.getPercentage(problem.re, problem.total) },
          { status: -3, count: this.getPercentage(problem.pe, problem.total) },
          { status: -2, count: this.getPercentage(problem.ce, problem.total) },
          { status: 4, count: this.getPercentage(problem.se, problem.total) },
        ];
      } else {
        // OI类型题目
        record = [
          { status: 0, count: this.getPercentage(problem.ac, problem.total) },
          { status: 8, count: this.getPercentage(problem.pa, problem.total) },
          { status: -1, count: this.getPercentage(problem.wa, problem.total) },
          { status: 1, count: this.getPercentage(problem.tle, problem.total) },
          { status: 2, count: this.getPercentage(problem.mle, problem.total) },
          { status: 3, count: this.getPercentage(problem.re, problem.total) },
          { status: -3, count: this.getPercentage(problem.pe, problem.total) },
          { status: -2, count: this.getPercentage(problem.ce, problem.total) },
          { status: 4, count: this.getPercentage(problem.se, problem.total) },
        ];
      }

      this.problemRecord = record;
      this.currentProblemTitle = problem.title;
    },
    getProblemList() {
      let queryParams = Object.assign({}, this.query);
      if (queryParams.difficulty == 'All') {
        queryParams.difficulty = '';
      }
      if (queryParams.oj == 'All') {
        queryParams.oj = '';
      } else if (!queryParams.oj) {
        queryParams.oj = 'Mine';
      }
      queryParams.tagId = queryParams.tagId + '';
      this.loadings.table = true;
      api.getProblemList(this.limit, queryParams).then(
        (res) => {
          this.total = res.data.data.total;
          this.problemList = res.data.data.records;
          if (this.isAuthenticated) {
            // 如果已登录，则需要查询对当前页面题目列表中各个题目的提交情况
            let pidList = [];
            for (let index = 0; index < this.problemList.length; index++) {
              pidList.push(this.problemList[index].pid);
            }
            if (pidList.length > 0) {
              // 必须当前页有显示题目才发送查询请求
              this.isGetStatusOk = false;
              let isContestProblemList = false; // 为了与比赛题目区分
              api
                .getUserProblemStatus(pidList, isContestProblemList)
                .then((res) => {
                  let result = res.data.data;
                  for (
                    let index = 0;
                    index < this.problemList.length;
                    index++
                  ) {
                    this.problemList[index]['myStatus'] =
                      result[this.problemList[index].pid].status;
                  }
                  this.isGetStatusOk = true;
                });
            }
          }
          this.loadings.table = false;
        },
        (res) => {
          this.loadings.table = false;
        }
      );
    },
    getTagList(oj) {
      if (oj == 'Mine') {
        oj = 'ME';
      }
      this.loadings.tag = true;
      api.getProblemTagList(oj).then(
        (res) => {
          this.tagList = res.data.data;
          let tidLen = this.query.tagId.length;
          let tagLen = this.tagList.length;
          for (let x = 0; x < tidLen; x++) {
            for (let y = 0; y < tagLen; y++) {
              if (this.query.tagId[x] == this.tagList[y].id) {
                this.filterTagList.push(this.tagList[y]);
                break;
              }
            }
          }
          this.buildFilterTagList = true;
          this.loadings.tag = false;
        },
        (res) => {
          this.loadings.tag = false;
        }
      );
    },
    changeTagVisible(visible) {
      this.$refs.problemList.getColumnByField('tag').visible = visible;
      this.$refs.problemList.refreshColumn();
    },
    onReset() {
      if (JSON.stringify(this.$route.query) != '{}') {
        this.$router.push({ name: 'ProblemList' });
      }
    },
    removeTag(tag) {
      this.filterTagList.splice(this.filterTagList.indexOf(tag), 1);
      this.filterByTag();
    },
    addTag(tag) {
      let len = this.filterTagList.length;
      for (let i = 0; i < len; i++) {
        if (this.filterTagList[i].id == tag.id) {
          return;
        }
      }
      this.filterTagList.push(tag);
      this.filterByTag();
    },
    filterByTag() {
      this.query.currentPage = 1;
      this.query.tagId = JSON.stringify(
        this.filterTagList.map((tagJson) => tagJson.id)
      );
      this.pushRouter();
    },
    filterByDifficulty(difficulty) {
      this.query.difficulty = difficulty;
      this.query.currentPage = 1;
      this.pushRouter();
    },
    filterByOJ(oj) {
      this.query.oj = oj;
      if (oj != 'All') {
        this.filterTagList = [];
      }
      this.query.currentPage = 1;
      this.getTagList(this.query.oj);
      this.pushRouter();
    },
    filterByKeyword() {
      this.query.currentPage = 1;
      this.pushRouter();
    },
    pickone() {
      api.pickone().then((res) => {
        myMessage.success(this.$i18n.t('m.Good_luck_to_you'));
        this.$router.push({
          name: 'ProblemDetails',
          params: { problemID: res.data.data.problemId },
        });
      });
    },
    getProblemUri(problemId) {
      this.$router.push({
        name: 'ProblemDetails',
        params: {
          problemID: problemId,
        },
      });
    },
    getLevelColor(difficulty) {
      return utils.getLevelColor(difficulty);
    },
    getLevelName(difficulty) {
      return utils.getLevelName(difficulty);
    },
    getIconColor(status) {
      return (
        'font-weight: 600;font-size: 16px;color:' +
        this.JUDGE_STATUS[status].rgb
      );
    },
  },
  computed: {
    ...mapGetters(['isAuthenticated']),
    OJName() {
      if (this.query.oj == 'Mine' || !this.$route.query.oj) {
        return this.$i18n.t('m.My_OJ');
      } else if (this.query.oj == 'All') {
        return this.$i18n.t('m.All');
      } else {
        return this.query.oj;
      }
    },
  },
  watch: {
    $route(newVal, oldVal) {
      if (newVal !== oldVal) {
        this.init();
        this.getData();
      }
    },
    isAuthenticated(newVal) {
      if (newVal === true) {
        this.init();
        this.getData();
      }
    },
  },
};
</script>

<style scoped>
.taglist-title {
  font-size: 21px;
  font-weight: 500;
}
/deep/.el-tag--dark {
  border-color: #d9ecff;
}
/deep/.tag-btn {
  margin-left: 4px !important;
  margin-top: 4px;
}
/deep/.vxe-checkbox .vxe-checkbox--label {
  overflow: unset !important;
}

#pick-one {
  margin-top: 10px;
}
/deep/ .el-card__header {
  border-bottom: 0px;
  padding-bottom: 0px;
}
@media screen and (min-width: 1200px) {
  /deep/ .el-card__body {
    padding-top: 0px;
    margin-top: 5px;
  }
}
@media only screen and (max-width: 767px) {
  .top-pt {
    padding-top: 10px;
  }
}
ul {
  float: right;
}
.title-a {
  color: #495060;
  font-family: inherit;
  font-size: 14px;
  font-weight: 500;
}
.el-progress {
  margin-top: 15px;
}

@media screen and (min-width: 1050px) {
  /deep/ .vxe-table--body-wrapper {
    overflow-x: hidden !important;
  }
}
.search-tag {
  font-size: 14px;
  line-height: 1.4285em;
}
.tag {
  margin-left: 10px;
  margin-top: 10px;
}
</style>
